
// 记录 表单子控件需要的属性，避免各个组件各种传递属性。
// 外部通过属性传入，然后内部建立状态。

import type { InjectionKey } from 'vue'
import { watch, nextTick } from 'vue'
import { defineStore, useStoreLocal } from '@naturefw/nf-state'
import type { IState } from '@naturefw/nf-state/dist/type'

/**
 * 维护 表单子控件的 meta 需要的状态
 */
export interface IStateItem {
  // itemMeta: any, // 传入的 要维护的 meta
  isRolad: boolean, // 扩展组件里设置初始值的依据
  sourceExtend: any, // 保存初始值
  base1: any, // 低代码需要的 meta，直接绑定
  base2: any, // 共用的基础属性，直接绑定
  extend: any, // 各个控件的扩展属性，同步
}

const flag = Symbol('state-item') as InjectionKey<string>

/**
 * 合并meta，低代码用的 + 共用的 + 扩展的
 * @param state 
 * @param reMeta 
 */
const setReMeta = (state: IStateItem, reMeta: any) => {
  // 删除 formItemMeta 之外的属性
  let keys = Object.keys(reMeta)
  keys.forEach(key => {
    if (key !== 'formItemMeta') {
      delete reMeta[key]
    }
  })

  // 设置通用属性
  keys = Object.keys(state.base2)
  keys.forEach(key => {
    const meta = state.base2[key]
    switch(key) {
      case 'kind':
      case 'controlType':
        break
      default:
        if (meta === '' || meta === null) {
          delete reMeta[key]
        } else {
          reMeta[key] = meta
        }
        break
    }
  })

  // 设置扩展属性
  keys = Object.keys(state.extend)
  keys.forEach(key => {
    const meta = state.extend[key]
    switch(key) {
      case 'kind':
      case 'controlType':
        break
      default:
        if (meta === '' || meta === null) {
          delete reMeta[key]
        } else {
          reMeta[key] = meta
        }
        break
    }
  })

}

/**
 * 把外部属性设置给状态
 */
const setState = (state: IStateItem, _meta: any) => {
  // 初始的时候，把外部属性设置给 state 
  let keys = Object.keys(_meta.formItemMeta)
  keys.forEach(key => {
    const meta = _meta.formItemMeta[key]
    switch(key) {
      case 'kind':
        break
      default:
        state.base1[key] = meta
        break
    }
  })
  state.base1.kind = Math.floor( state.base1.controlType / 10 )

  keys = Object.keys(_meta)
  keys.forEach(key => {
    const meta = _meta[key]
    switch(key) {
      case 'kind':
      case 'formItemMeta':
        break
      default:
        if (state.base2[key]) {
          // 基础属性里面有，
          state.base2[key] = meta
        } else {
          // 没有的设置给扩展属性
          state.sourceExtend[key] = meta
        }
        break
    }
  })
  state.isRolad = !state.isRolad
  nextTick(() => {
    state.isRolad = !state.isRolad
  })

}

/**
 * 注册一个 表单子控件的 状态
 * @param reMeta 要维护的 meta，表单子控件的属性，一个。
 * @returns 
 */
export function regItemState(reMeta: any) {

  // 定义状态
  const state = defineStore<IStateItem>(flag, {
    state: () => {
      return {
        isRolad: false, // 扩展组件里设置初始值的依据
        sourceExtend: {}, // 保存初始值
        // itemMeta: {}, // 【好像没用了】传入的 要维护的 meta
        base1: {}, // 低代码需要的 meta，直接绑定
        base2: {}, // 共用的基础属性，直接绑定
        extend: {}, // 各个控件的扩展属性，同步
      }
    },
    getters: {},
    actions: {
      // 外部设置内部的属性
      setMeta(_meta: any) {
        setState(this, _meta)
      }
    }
  },
  { isLocal: true})

  // 监听，合并输出属性
  // 低代码的 meta
  watch(state.base1, () => {
    const keys = Object.keys(state.base1)
    keys.forEach(key => {
      const meta = state.base1[key]
      switch(key) {
        case 'kind':
        case 'kind_controlType':
          break
        default:
          reMeta.formItemMeta[key] = meta
          break
      }
    })
  }) //, { immediate: true}

  // 共用的基础属性和扩展属性
  watch([state.base2, state.extend], () => {
    setReMeta(state, reMeta)
  }) // , { immediate: true}
  

  return state
}


/**
 * 子组件用 inject 获取状态 
 * @returns
 */
export function getItemState() {
  return useStoreLocal<IStateItem & IState>(flag)
}
